package com.example.securitydemo.config;

import com.example.securitydemo.filter.JwtRequestFilter;
import com.example.securitydemo.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletResponse;

/**
 * SecurityConfig 类是Spring Security的配置类，用于配置应用程序的安全策略。
 * 该类启用了Web安全，并配置了用户认证、授权、JWT过滤器等。
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private UserDetailsService customUserDetailsService; // 替换为具体实现类

    @Autowired
    public void setUserDetailsService(UserDetailsService customUserDetailsService) {
        this.customUserDetailsService = customUserDetailsService;
    }

    @Autowired
    private JwtUtil jwtUtil; // JWT工具类，用于生成和验证JWT令牌

    /**
     * 配置认证管理器，使用自定义的UserDetailsService来加载用户信息。
     *
     * @param auth AuthenticationManagerBuilder对象，用于构建认证管理器
     * @throws Exception 如果配置过程中发生错误
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService); // 使用具体实现
    }

    /**
     * 配置HTTP安全策略，包括禁用CSRF保护、设置授权规则、配置会话管理等。
     * 此外，还添加了JWT过滤器来处理JWT令牌的验证。
     *
     * @param http HttpSecurity对象，用于配置HTTP安全策略
     * @throws Exception 如果配置过程中发生错误
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/authenticate").permitAll()
            .anyRequest().authenticated()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            // 添加异常处理配置，未认证时返回401
            .and()
            .exceptionHandling()
            .authenticationEntryPoint((request, response, authException) -> 
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
        ;

        http.addFilterBefore(new JwtRequestFilter(jwtUtil, customUserDetailsService), UsernamePasswordAuthenticationFilter.class);
    }

    /**
     * 将AuthenticationManager暴露为Spring Bean，以便在其他地方使用。
     *
     * @return AuthenticationManager对象
     * @throws Exception 如果获取过程中发生错误
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 配置密码编码器，这里使用BCryptPasswordEncoder进行安全的密码加密。
     *
     * @return PasswordEncoder对象
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
